using System;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

namespace muduoDotNet.Tests
{
    public class TimerQueueTest
    {
        [Fact]
        public void TestAddTimer()
        {
            var loop = new EventLoop();
            
            bool called = false;
            var timerId = loop.AddTimer(() => { called = true; }, 0.1);
            
            Assert.NotEqual(default(TimerId), timerId);
            Assert.False(called);
            
            loop.Dispose();
        }

        [Fact]
        public void TestTimerExpiration()
        {
            var loop = new EventLoop();
            
            bool called = false;
            var timerId = loop.AddTimer(() => { called = true; }, 0.05); // 50ms
            
            // 在后台启动事件循环
            var loopTask = Task.Run(() => loop.Start());
            
            // 等待定时器触发
            Thread.Sleep(200); // 200ms 足够让定时器触发
            
            loop.Stop();
            loopTask.Wait(1000);
            
            Assert.True(called);
            
            loop.Dispose();
        }

        [Fact]
        public void TestRepeatingTimer()
        {
            var loop = new EventLoop();
            
            int callCount = 0;
            var timerId = loop.AddTimer(() => { callCount++; }, 0.05, 0.05); // 50ms interval
            
            // 在后台启动事件循环
            var loopTask = Task.Run(() => loop.Start());
            
            // 等待定时器多次触发
            Thread.Sleep(250); // 250ms 应该能触发多次
            
            loop.Stop();
            loopTask.Wait(1000);
            
            Assert.True(callCount >= 2); // 至少触发两次
            
            loop.Dispose();
        }

        [Fact]
        public void TestCancelTimer()
        {
            var loop = new EventLoop();
            
            bool called = false;
            var timerId = loop.AddTimer(() => { called = true; }, 0.1);
            
            // 立即取消定时器
            loop.CancelTimer(timerId);
            
            // 启动事件循环并等待足够长的时间
            var loopTask = Task.Run(() => loop.Start());
            
            Thread.Sleep(200); // 等待足够长的时间
            
            loop.Stop();
            loopTask.Wait(1000);
            
            Assert.False(called);
            
            loop.Dispose();
        }
    }
}